package com.shipwe.loans.utils.imgcovert

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import kotlin.math.ceil

class ImageCompress(
    private val srcImg: File,
    private val tagImg: File,
    private val focusAlpha: Boolean
) {
    private var srcWidth = 0
    private var srcHeight = 0

    init {
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        options.inSampleSize = 1

        BitmapFactory.decodeStream(FileInputStream(srcImg), null, options)
        srcWidth = options.outWidth
        srcHeight = options.outHeight
    }

    private fun computeSize(): Int {
        srcWidth = if (srcWidth % 2 == 1) srcWidth + 1 else srcWidth
        srcHeight = if (srcHeight % 2 == 1) srcHeight + 1 else srcHeight

        val longSide = srcWidth.coerceAtLeast(srcHeight)
        val shortSide = srcWidth.coerceAtMost(srcHeight)

        val scale = shortSide.toFloat() / longSide
        return when {
            scale <= 1 && scale > 0.5625 -> when {
                longSide < 1664 -> 1
                longSide < 4990 -> 2
                longSide in 4991..10239 -> 4
                else -> longSide / 1280
            }

            scale <= 0.5625 && scale > 0.5 -> if (longSide / 1280 == 0) 1 else longSide / 1280
            else -> ceil(longSide / (1280.0 / scale)).toInt()
        }
    }

    private fun rotatingImage(bitmap: Bitmap, angle: Int): Bitmap {
        val matrix = Matrix()
        matrix.postRotate(angle.toFloat())
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    }

    @Throws(IOException::class)
    fun compress(): File {
        val options = BitmapFactory.Options()
        options.inSampleSize = computeSize()

        var tagBitmap = BitmapFactory.decodeStream(FileInputStream(srcImg), null, options)
        if (tagBitmap != null) {
            val stream = ByteArrayOutputStream()

            if (ImageChecker.isJPG(FileInputStream(srcImg))) {
                tagBitmap =
                    rotatingImage(tagBitmap, ImageChecker.getOrientation(FileInputStream(srcImg)))
            }

            tagBitmap.compress(
                if (focusAlpha) Bitmap.CompressFormat.PNG else Bitmap.CompressFormat.JPEG,
                60,
                stream
            )
            tagBitmap.recycle()

            val fos = FileOutputStream(tagImg)
            fos.write(stream.toByteArray())
            fos.flush()
            fos.close()
            stream.close()
        }

        return tagImg
    }
}
